#include <cstring>
#include <inputmanager.hpp>
#include <input_kbdev.hpp>
#include <input_fingermoduledev.hpp>
#include <iostream>
#include <boost/thread.hpp>
#include <inputdev_func.hpp>
#include <elog.h>
#include <string>

using namespace std;

static boost::mutex mutex; 


static void thread_run_input_status_report(const int &id);
static void thread_run_input_enroll(const int &id);
static void thread_run_input_auth(const int &id);


input_dev_param::input_dev_param(){
    queue = NULL;
    input_events = NULL;

    mode   = 0; 
    status = 0;      // 标识结果成功还是失败 
    detail = 0;      // 标识结果失败时的具体原因  
    isfuncdone = 0;  // 判断当前功能是否结束的标志，注册需要两步骤。而验证只需要一步骤。

    cancel_reason = 0; // 取消原因，手动操作的取消、系统功能切换而导致的自动取消、检测到错误操作而导致的取消

    input_type = 0;    
    input_code = 0; 
    input_value = 0; 
    execption_id = input_no_ececption; 
    cancel_reason = 0;
    memset(content, 0, sizeof(content));
}
    

void clear_input_dev_param(input_dev_param* obj){

    //queue = NULL;
    //input_events = NULL;

    obj->mode   = 0; 
    obj->status = 0;     // 标识结果成功还是失败 
    obj->detail = 0;      // 标识结果失败时的具体原因  
    obj->isfuncdone = 0; // 判断当前功能是否结束的标志，注册需要两步骤。而验证只需要一步骤。


    obj->input_type = 0;    
    obj->input_code = 0; 
    obj->input_value = 0; 

    obj->execption_id = 0; 
    obj->cancel_reason = 0; // 取消原因，手动操作的取消、系统功能切换而导致的自动取消、检测到错误操作而导致的取消

    memset(obj->content, 0, sizeof(obj->content));

}

// Input Manager -- 职责1, 为了能和子类、以及观察者正常交互， 去创建必要的资源条件，即创建一些必要的线程。
void user_function_do_once_only(){

    // 该线程： 接收子类事件消息。同时，需要上报事件给观察者 
	boost::thread t_thread_input_statue_report(thread_run_input_status_report, 0);

	boost::thread t_thread_input_enroll(thread_run_input_enroll,       1);

    boost::thread t_thread_input_auth(thread_run_input_auth,           2);

}

inputmanager* inputmanager::pinputmanager_instance = NULL;

inputmanager* inputmanager::get_inputmanager(){
 
    boost::unique_lock<boost::mutex> lock(mutex);
    
    if(pinputmanager_instance == NULL)  {

        pinputmanager_instance = new inputmanager;

        inmanager_create_alldevs();

        user_function_do_once_only();
    }
    
    return pinputmanager_instance;

}


// 子类被构造的时候会导致父类被构造，有些事情只能发生一次，例如状态初始化，只需要初始化一次即可，
// 也就是说，放在这里会受子类的变化，代码执行次数是不稳定的。解决方法如下：
 // 可以在父类的构造函数内使用单例模式。让创建线程这种事情，全都在单例类去做掉。 
//经过这样改善，会使得阅读我代码的人可以更好地理解我的用意。别扭的感觉会完全消失。
inputmanager:: inputmanager(){

}

inputmanager:: ~inputmanager(){
    cout << " ~inputmanager()" << endl;
    
}



// Input Manager -- 职责2
// 观察者模式部分
void inputmanager::attach_event_listener(abstract_state_manager_isalso_listener*listener){

    this->observers_list.push_back(listener);
}

void inputmanager:: detach_event_listener(abstract_state_manager_isalso_listener*listener){

    /* find():  find失败时，返回值就是传进去的第2个实参，即这里的m_lst.end() */
    list<abstract_state_manager_isalso_listener*>::iterator iter = find(observers_list.begin(), observers_list.end(), listener);
    if (iter != observers_list.end())
    {
        observers_list.erase(iter);
    }
}

void inputmanager:: notify(){

    list<abstract_state_manager_isalso_listener*>::iterator iter = this->observers_list.begin();
    for (; iter != observers_list.end(); iter++)
    {
         /* 调用观察者的更新接口，传入被观察者类自己的this指针 */
        (*iter)->Update(this);
    }
}


void inputmanager::setState(input_dev_param *iparam) {

    this->param.input_type    = iparam->input_type;    
    this->param.input_code    = iparam->input_code;
    this->param.input_value   = iparam->input_value;
    this->param.execption_id  = iparam->execption_id;
    this->param.cancel_reason = iparam->cancel_reason;
}


input_dev_param* inputmanager::getstate() {

    return &param;
}


/**
 *   为了能和子类正常交互， 去创建必要的条件，即接收子类事件消息。同时，需要上报事件给观察者 。
*/
static void thread_run_input_status_report(const int &id){

    cout << "thread_run_input_statue: report" << endl;

    boost::circular_buffer<c_indevval> queue(10);

    input_dev_param  param;
    param.queue = &queue;
    log_d("&param = %d \n", &param);

    string s_dev_types = combine_devtypes(1, key_inputdev_type);

    inmanager_cmd(const_cast<char*>(s_dev_types.c_str()), e_input_cmd_notifystatus,  &param);
    

    while(1){

        boost::unique_lock<boost::mutex> lock(param.mutex);        

        log_d("---cond.wait ...--- \n");
        param.cond.wait(lock); 

        boost::circular_buffer<c_indevval>::iterator it = param.queue->begin();

        //接收到消息后，发送给观察者
        param.input_type = it->type;    
        param.input_code = it->code;
        param.input_value = it->value;
        param.execption_id  = get_execption_id_from_info(it->execption_info); 
        param.cancel_reason = get_execption_detail_from_info(it->execption_info); 

        log_w("type=%d, code=%c, val=%d, execp=0x%x\n", it->type, it->code, it->value, it->execption_info);

        param.queue->pop_front();

        lock.unlock();
        log_d("---cond.wait Done!--- \n");

   #if 1
        inputmanager* pinputmanager = inputmanager::get_inputmanager();
        pinputmanager->setState(&param);
        pinputmanager->notify();

    #endif

    }
}


static void thread_run_input_enroll(const int &id){

    cout << "thread_run_input: enroll" << endl;
}

static void thread_run_input_auth(const int &id){
    
    cout << "thread_run_input: auth" << endl;
}


int inputmanager::suspend(void){

}

int inputmanager::resume(void){

}

int inputmanager::enroll( input_dev_param *param){
}

int inputmanager::cancel_enroll( input_dev_param *param){
}

int inputmanager::authenticate( input_dev_param *param){
}

int inputmanager::cancel_authenticate( input_dev_param *param){
}

int inputmanager::delete_user( input_dev_param *param){
}

int inputmanager::cancel_delete_user( input_dev_param *param) {
}

int inputmanager::get_userid( input_dev_param *param){
}

int inputmanager::cancel_get_userid( input_dev_param *param){
}

int inputmanager::notify_resource_to_inputdev( input_dev_param *param){
}

int inputmanager::notify_param_handle( input_dev_param *param){
}

